package ldh.im.fxbase.service;

import ldh.im.dto.enums.MessageType;
import ldh.im.fxbase.dao.ImMessageDao;
import ldh.im.fxbase.dao.ImMessageSendDao;
import ldh.im.fxbase.dao.ImSessionDao;
import ldh.im.fxbase.data.pojo.ImMessage;
import ldh.im.fxbase.data.pojo.ImSession;
import ldh.im.fxbase.data.pojo.status.ImMessageActionStatus;
import ldh.im.fxbase.data.pojo.status.ImMessageRefType;
import ldh.im.fxbase.data.pojo.status.ImMessageStatus;
import ldh.im.fxbase.util.BeanFactory;
import ldh.im.fxbase.util.FileUtil;
import ldh.im.fxbase.util.MessageUtil;
import ldh.im.util.ConfigUtil;

import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

public class MessageService {

    private ImMessageDao imMessageDao = BeanFactory.getInstance().getBean(ImMessageDao.class);
    private ImMessageSendDao imMessageSendDao = BeanFactory.getInstance().getBean(ImMessageSendDao.class);
    private ImSessionDao imSessionDao = BeanFactory.getInstance().getBean(ImSessionDao.class);

    public void withdrawMessage(String userId, ImMessage imMessage) throws SQLException {
        imMessage.setStatus(ImMessageStatus.withdraw);
        imMessageDao.updateMessageStatus(imMessage.getId(), ImMessageStatus.withdraw, ImMessageActionStatus.withdraw);
    }

    public void withdrawedMessage(String userId, ImMessage imMessage) throws SQLException {
        imMessage.setStatus(ImMessageStatus.withdrawed);
        imMessage.setUpdateDateTime(new Date());
        imMessageDao.updateMessageStatus(imMessage.getId(), ImMessageStatus.withdrawed, ImMessageActionStatus.withdrawed);

        if (imMessage.getMessageType().isFile()) {
            FileService fileService = BeanFactory.getInstance().getBean(FileService.class);
            ImSession imSession = imMessage.getImSession();
            if (imSession == null) {
                imSession = imSessionDao.getSessionById(imMessage.getSessionId());
            }
            fileService.deleteFile(userId, imSession.getServerId(), imMessage.getServerId());
        }
    }

    public void cleanMessage(String userId, Long sessionId) throws SQLException {
        List<MessageType> messageTypes = null;
        int pageSize = 1000;
        List<ImMessage> messages = imMessageDao.getMessagesBySessionId(sessionId, null, messageTypes, 0, pageSize);

        // 先删除附件
        for (ImMessage message : messages) {
            if (!message.getMessageType().isFile()) continue;
            message.initMessageExt();
            if ((message.getMessageExt().getRemote() && !FileUtil.isCaptureFile(message)) || FileUtil.isCaptureFile(message)) {
                deleteFile(ConfigUtil.getRoot() + message.getContent());
            }
        }
        List<Long> messageIds = messages.stream().map(ImMessage::getId).collect(Collectors.toList());
        imMessageDao.cleanMessages(userId, messageIds);
        imMessageSendDao.cleanMessageSends(messageIds);
        if (messages.size() == pageSize) {
            cleanMessage(userId, sessionId);
        }
    }

    public void handleImageSize(List<ImMessage> messages) throws SQLException {
        List<ImMessage> updateMessages = new ArrayList<>(messages.size());
        for (ImMessage message : messages) {
            if (message.getMessageType() != MessageType.Image) continue;
            if (message.getMessageExt() == null) {
                message.initMessageExt();
            }
            if (message.getMessageExt().getImageWidth() == null || message.getMessageExt().getImageHeight() == null) {
                String path = FileUtil.getFilePath(message);
                int[] sizes = FileUtil.getImageSize(new File(path));
                if (sizes != null && sizes.length == 2) {
                    message.getMessageExt().setImageWidth(sizes[0]);
                    message.getMessageExt().setImageHeight(sizes[1]);
                    message.initExt();
                    updateMessages.add(message);
                }
            }
        }
        imMessageDao.batchUpdateMessageExts(updateMessages);
    }

    private void deleteFile(String filePath) {
        try {
            Files.deleteIfExists(Paths.get(filePath));
        } catch (Exception e) {

        }
    }
}
